<?php

class musicbrainz extends feed {
	
	static $cue = array();
	
	static private function filterQuery($query) {
		$filter = array(
			"and",
			"live",
			"video",
			"remix", // ???
			"part",
			"at",
			"music",
			"lyrics",
			"official",
			"song",
			"mix",
			"hq",
			"concert",
			"hd",
			"ft",
			"feat",
			"version",
			"full"
		);
		// TODO replace only entire words instead of strings
		// return str_ireplace($filter, "", $query);
		
		// use word boundaries
		foreach($filter as $rule) {
			$query = preg_replace("/\b".$rule."\b/i", "", $query);
		}
		return $query;
		
	}
	
	static public function getSimilarity(video $video) {
		// overall similarity
		similar_text(strtolower($video->getName()), strtolower($video->getMeta("mb_artist") . " " . $video->getMeta("mb_title")), $global_perc);
		// artist similarity
		similar_text(strtolower($video->getMeta("parsed_artist")), strtolower($video->getMeta("mb_artist")), $artist_perc);
		// title similarity
		similar_text(strtolower($video->getMeta("parsed_title")), strtolower($video->getMeta("mb_title")), $title_perc);
		// return average, artist weight = 2
		return array_sum(array($global_perc, $artist_perc * 2, $title_perc)) / 4;
	}
	
	static function queryTrack($query) {
		
		$result = array();
		
		// get url
		$url = self::getQueryTrackUrl($query);
		
		// get feed
		$xml = self::loadRaw($url, config::getInstance()->musicbrainz_ttl);
		
		if (!$xml) {
			$xml = "<?xml/>";			
		}
		
		$track = phpQuery::newDocumentXML($xml)->find("metadata")->find("track-list")->find("track:first");
				
		$result['mb_score'] 		= pq($track)->attr("ext:score");
		$result['mb_track_id'] 		= pq($track)->attr("id");
		$result['mb_title'] 		= pq($track)->children("title")->text();
		$result['mb_artist_id'] 	= pq($track)->children("artist")->attr("id");
		$result['mb_artist'] 		= pq($track)->children("artist")->find("name")->text();
		$result['mb_album_id'] 		= pq($track)->children("release-list")->find("release[type=Album]:first")->attr("id");
		$result['mb_album'] 		= pq($track)->children("release-list")->find("release[type=Album]:first")->find("title")->text(); 

		return $result;		
	}
	
	static public function getQueryTrackUrl($query) {
		// prepare query for sending to youtube
		$query = urlencode(self::prepareQuery($query));
		return "http://musicbrainz.org/ws/1/track/?type=xml&limit=1&query=".$query;
	}
	
	static private function prepareQuery($query) {
		// http://musicbrainz.org/doc/Text_Search_Syntax/Advanced_Syntax
		// http://lucene.apache.org/java/3_0_1/queryparsersyntax.html
		$illegal = ".+-&|!(){}[]^\"~*?:\\";
		$query = self::filterQuery($query);
		$query = str_replace(str_split($illegal), " ", $query);
		return $query;
	} 
	
	static function addToCue($video_id) {
		self::$cue[] = $video_id;
	}
	
	static function hasCue() {
		return count(self::$cue);
	}
	
	static function getCueUrl() {
		return "http://" . config::getInstance()->site_url . "/video/runMusicBrainzCue/null";
	}
	
	static function runCueAsync() {
		curl::getAsyncPostRequest(self::getCueUrl(), array("cue" => serialize(self::$cue)));
	}
		
	static function runCue($cue = null, $mode = 'html') {
		
		if (empty($cue) && !empty(self::$cue)) {
			$cue = self::$cue;
		} 
		
		if ($mode === 'null') {
			// http://stackoverflow.com/questions/124462/asynchronous-php-calls
			while(ob_get_level()) ob_end_clean();
			header('Connection: close');
			ignore_user_abort();
			ob_start();
			$size = ob_get_length();
			header("Content-Length: $size");
			ob_end_clean();
			flush();
			set_time_limit(60 * 5);
		}
		
		if (!$cue) { return false; }

		// loop video ids
		foreach ($cue as $video_id) {
			$video = new video($video_id);
			switch ($mode) {
			case 'debug':		
				echo $video_id . " : ";		
				echo $video->getName()." : <a href=\"";
				echo self::getQueryTrackUrl($query = self::prepareQuery($video->getName()));
				echo "\">$query</a><br/>";
				break;
			case 'null':
			default:
				$video->addMetaFromMusicBrainz();
				sleep(config::getInstance()->musicbrainz_sleep);
				break;
			}
		}		
	}
	
}

?>